//
//  NSObjectGCDAsyncSocket.m
//  attendance
//
//  Created by dgc on 15/7/7.
//  Copyright (c) 2015年 dgc. All rights reserved.
//

#import "NSObjectGCDAsyncSocket.h"
#import "ReuseMethod.h"
@implementation NSObjectGCDAsyncSocket
{
    ReuseMethod* reuseMethod;
}
/**
 *  单例
 *
 *  @return
 */
+(NSObjectGCDAsyncSocket *)defaultSocket
{
    //socket只会实例化一次
    static NSObjectGCDAsyncSocket* socket=nil;
    //保证线程安全，defaultSocket只执行一次
    static dispatch_once_t once;
    dispatch_once(&once, ^
    {
        socket=[[NSObjectGCDAsyncSocket alloc] init];
    });
    return socket;
}

/**
 *  初始化
 *
 *
 *  @return self
 */
-(instancetype)init
{
    self=[super init];
    if (self)
    {
        socket=[[GCDAsyncSocket alloc] initWithDelegate:self
                                          delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
        self.GCDASHost=SocketHost;
        self.GCDASPort=SocketPort;
        self.GCDSocketType0=GCDSocketTypeDefault;
        reuseMethod=[ReuseMethod new];
    }
    return self;
}
/**
 *  发送链接请求
 */
-(void)startConnect
{
//    switch (self.GCDSocketType0)
//    {
//        case GCDSocketTypeDefault:
//        {
//
//        }
//            break;
//        case GCDSocketTypeChat:
//        {
//            
//        }
//            break;
//        default:
//            break;
//    }
    //先确定断开连接再开始链接
    if (socket.isConnected)
    {
        NSLog(@"主动断开");
        [socket disconnect];
        
    }

    NSError* error;
    [socket connectToHost:self.GCDASHost
                    onPort:self.GCDASPort
                     error:&error];
    if (error)
    {
        NSLog(@"%s\n%@",__FUNCTION__,error.localizedDescription);
    }
}
#pragma mark - GCDAsyncSocketDelegate
/**
 *  链接成功
 *
 *  @param sock sock实例
 *  @param host IP
 *  @param port 端口
 */
-(void)socket:(GCDAsyncSocket *)sock
didConnectToHost:(NSString *)host
         port:(uint16_t)port
{
//    NSLog(sock.isConnected?@"YES":@"NO");
//    if (sock.isConnected)
//    {

 //nsstring上传需要加"\n"分隔符方可上传成功
/*
 [sock writeData:[@"ABCABCABCABCABCABC\n" dataUsingEncoding:NSUTF8StringEncoding]
 withTimeout:-1
 tag:0];
 */

/*
 NSDictionary* nsDictionaryUser=@{@"gpsinfo":@"Gpsinfo",
 @"pswd":self.passWord,
 @"gpstype":@(2015),
 @"name":self.name,
 };

        NSDictionary* agrement=@{@"vertion":@(1),
                                 @"type1":@(2),
                                 @"type2":@(0),
                                 @"type3":@(0)};
*/
    switch (self.GCDSocketType0)
    {
        case GCDSocketTypeDefault:
        {
            if ([NSJSONSerialization isValidJSONObject:self.writeData])
            {
                //            NSLog(@"%s",__FUNCTION__);
                
                NSError* error;
                //先转nsdata再转nsstring是为了保证nsdictionary格式不变
                NSData *nsDataUser= [NSJSONSerialization dataWithJSONObject:self.writeData
                                                                    options:NSJSONWritingPrettyPrinted
                                                                      error:&error];
                NSString* json=[[NSString alloc] initWithData:nsDataUser
                                                     encoding:NSUTF8StringEncoding];
                
                json=[json stringByReplacingOccurrencesOfString:@"\n"
                                                     withString:@""];
                //            json=[json stringByReplacingOccurrencesOfString:@" "
                //                                                 withString:@""];
                json=[json stringByAppendingString:@"\n"];
                //            NSLog(@"json:%@",json);
                
                [sock writeData:[json dataUsingEncoding:NSUTF8StringEncoding]
                    withTimeout:-1
                            tag:SocketTagDefault];
                //保持读取的长连接
                [sock readDataWithTimeout:-1
                                      tag:SocketTagDefault];
                
                if (error)
                {
                    NSLog(@"%s\n%@",__FUNCTION__,[error localizedDescription]);
                    NSLog(@"%s\n%@",__FUNCTION__,[error localizedFailureReason]);
                }
                
            }
            

        }
            break;
            case GCDSocketTypeChat:
        {
            NSLog(@"%s",__FUNCTION__);

            self.GCDTimer=[NSTimer scheduledTimerWithTimeInterval:5.0f
                                                           target:self
                                                         selector:@selector(GCDWriteData)
                                                         userInfo:nil
                                                          repeats:YES];
            
            [self.GCDTimer fire];
            
            //保持读取的长连接
            [sock readDataWithTimeout:-1
                                  tag:SocketTagChat];

            
        }
            break;
            
        default:
            break;
    }

//    }
 
}
/**
 *  发送数据成功
 *
 *  @param sock  sock实例
 *  @param tag  标记sock
 */
-(void)socket:(GCDAsyncSocket *)sock
didWriteDataWithTag:(long)tag
{
    switch (self.GCDSocketType0)
    {
        case GCDSocketTypeChat:
        {
            NSLog(@"%s",__FUNCTION__);


        }
            break;
            
        default:
            break;
    }
}
/**
 *  已经获取到数据
 *
 *  @param sock sock实例
 *  @param data 获取到的数据
 *  @param tag  标记sock
 */
-(void)socket:(GCDAsyncSocket *)sock
  didReadData:(NSData *)data
      withTag:(long)tag
{
    
//    NSLog(@"%s",__FUNCTION__);
    NSError* error=nil;
    

    NSDictionary* json=(NSDictionary*)[NSJSONSerialization JSONObjectWithData:data
                                                       options:NSJSONReadingAllowFragments
                                                         error:&error];
    
//    NSLog([NSJSONSerialization isValidJSONObject:json]?@"is ValidJSONObject":@"is't ValidJSONObject");
    if (error)
    {
//        NSLog(@"%s\n%@",__FUNCTION__,[error localizedDescription]);
//         NSLog(@"%s\n%@",__FUNCTION__,[error localizedFailureReason]);
    }

    switch (self.GCDSocketType0)
    {
        case GCDSocketTypeDefault:
        {
            self.didReadData(json);

            [sock disconnect];

        }
            break;
            case GCDSocketTypeChat:
        {
//            //保持读取的长连接
//            [sock readDataWithTimeout:-1
//                                  tag:11];

            NSLog(@"%s\n%@",__FUNCTION__,[[NSString alloc] initWithData:data
                                                               encoding:NSUTF8StringEncoding]);

        }
            break;
            
        default:
            break;
    }
    
}

/**
 *  链接出错
 *
 *  @param sock sock实例
 *  @param err  错误参数
 */
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock
                 withError:(NSError *)err
{
    self.didReadData(nil);

    switch (self.GCDSocketType0)
    {
        case GCDSocketTypeChat:
        {
            NSLog(@"%s\n%@\n%@",__FUNCTION__,[err localizedDescription],[err localizedFailureReason]);

            [self startConnect];
        }
            break;
        case GCDSocketTypeDefault:
        {
//            NSLog(@"%s\n%@\n%@",__FUNCTION__,[err localizedDescription],[err localizedFailureReason]);

        }
            break;
 
            
        default:
            break;
    }

    
}
- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock;
{
    NSLog(@"%s",__FUNCTION__);
    
    switch (self.GCDSocketType0)
    {
        case GCDSocketTypeDefault:
        {
            
        }
            break;
        case GCDSocketTypeChat:
        {
//            //保持读取的长连接
//            [sock readDataWithTimeout:-1
//                                  tag:11];
//
        }
            break;

        default:
            break;
    }

}
#pragma mark - Method
/**
 *  保证json数据格式
 *
 *  @param data
 *
 *  @return
 */
-(NSData*)GCDCheckData:(NSData*)data
{
    NSString* json=[[NSString alloc] initWithData:data
                                         encoding:NSUTF8StringEncoding];
    
    json=[json stringByReplacingOccurrencesOfString:@"\\n"
                                         withString:@""];
    
    json=[json stringByReplacingOccurrencesOfString:@"\\r"
                                         withString:@""];
    
    json=[json stringByReplacingOccurrencesOfString:@"\\t"
                                         withString:@""];

    NSLog(@"%s\n%@",__FUNCTION__,json);
    json=[json stringByAppendingString:@"\n"];

    return [json dataUsingEncoding:NSUTF8StringEncoding];
}
/**
 *  心跳包
 */
-(void)GCDWriteData
{
    NSDictionary* dictionary=@{@"sendUser":@"777777",
                               @"message":@"心跳包",
                               @"messageType":@"1",
                               @"groupType":@"0",
                               @"receiveUser":@""};
    
    [self->socket writeData:[reuseMethod RMJSONData:dictionary]
                             withTimeout:5
                                     tag:SocketTagChat];
}

@end
